home *** CD-ROM | disk | FTP | other *** search
Java Source | 2000-10-10 | 13.1 KB | 388 lines |
- /**
- Company: Eyematic Interfaces
- Project: Shout3D 2.0 Sample Code
- Class: MultiTestPanel
- Date: April 26, 1999
- Description: Tests various features. Press '?' for Java Panel instructions
- (C) Copyright Eyematic Interfaces, Inc. - 1997-2000 - All rights reserved
- */
-
- package applets;
-
- import java.applet.*;
- import java.awt.*;
- import java.awt.image.*;
- import java.io.*;
- import java.util.Date;
- import java.util.Vector;
- import java.net.URL;
- import shout3d.*;
- import shout3d.math.*;
- import shout3d.core.*;
-
- /**
- *
- * Panel that tests lots of features, including
- * little markers that show the location and normal of geometry
- * below the mouse.
- *
- * Press '?' to see instructions in the Java Panel.
- *
- * @author Paul Isaacs
- * @author Jim Stewartson
- * @author Dave Westwood
- */
-
- public class MultiTestPanel extends Shout3DPanel implements DeviceObserver {
- boolean locationTracking = false;
- boolean normalTracking = false;
- int curMouseX, curMouseY;
- boolean mouseMoved = false;
-
- /**
- * Constructor
- */
- public MultiTestPanel(Shout3DApplet applet){
- super(applet);
- }
-
- public void customInitialize(){
- // Register to watch rendering, the keyboard and mouse
- addDeviceObserver(this,"KeyboardInput", null);
- addDeviceObserver(this,"MouseInput", null);
- getRenderer().addRenderObserver(this,null);
-
- String normalTrackingString = applet.getParameter("normalTracking");
- if (normalTrackingString != null && normalTrackingString.equals("true"))
- normalTracking = true;
- else
- normalTracking = false;
-
- String locationTrackingString = applet.getParameter("locationTracking");
- if (locationTrackingString != null && locationTrackingString.equals("true"))
- locationTracking = true;
- else
- locationTracking = false;
-
- }
-
- /**
- * Clean up by unregistering observers
- */
- protected void finalize() throws Throwable {
- getRenderer().removeRenderObserver(this);
- removeDeviceObserver(this,"KeyboardInput");
- removeDeviceObserver(this,"MouseInput");
- super.finalize();
- }
-
- /**
- * Override to do a pick and show results, if desired.
- * Tracking of the pick must be performed during onPostRender.
- * This is because multithreading may put rendering in a separate thread,
- * but trackPick() adds/removes children.
- * Hence, unless we insure that trackPick() occurs between renders,
- * the children could disappear during the middle
- * of a render, which can cause null pointer exceptions.
- *
- * Note that no onPreRender() method is implemented in this class,
- * even though it is required for all classes implementing RenderObserver.
- * This is because the super class implements RenderObserver fully
- * and onPreRender is inherited.
- * Hence this class needs only to override the onPostRender() method,
- * making sure to call super.onPostRender(r,userData) within the body
- * of the method.
- */
- public void onPostRender(Renderer r, Object userData) {
- super.onPostRender(r,userData);
- if (mouseMoved && (locationTracking || normalTracking))
- trackPick();
- }
-
- //{{ DeviceObserver methods
- /**
- * Processes mouse and keyboard input.
- *
- * Moving the mouse records the mouse location for later use during
- * trackPick(), which is called between renders (see onPostRender above)
- *
- * Pressing keyboard keys performs any of a series of tests.
- *
- */
- public boolean onDeviceInput(DeviceInput di, Object userData) {
- if (di instanceof MouseInput){
- if (((MouseInput)di).which == MouseInput.MOVE) {
- curMouseX = ((MouseInput)di).x;
- curMouseY = ((MouseInput)di).y;
- // Do not do the pick right here. Set this flag so it will
- // occur during onPostRender. See onPostRender for why.
- mouseMoved = true;
- }
- }
- else {
- KeyboardInput ki = (KeyboardInput) di;
- if (ki.which == KeyboardInput.PRESS) {
- switch(ki.key) {
- case 'w': case 'W':
- // W key pressed. Write the scene to a little text frame
- // (WriterTextFrame is defined in this file.
- if (getScene() != null) {
- WriterTextFrame myFrame = new WriterTextFrame();
- myFrame.resize(400, 600);
- myFrame.show();
-
- ByteArrayOutputStream os = new ByteArrayOutputStream();
- PrintStream ps = new PrintStream(os);
- Shout3DWriter writer = new Shout3DWriter();
- writer.write(getScene(),ps);
- myFrame.getTextArea().setText(os.toString());
- }
- return true;
- case 'n': case 'N':
- // N key pressed. Toggle normal-tracking. Each time the mouse moves, do a
- // pick and place arrow at picked location, pointing in direction of normal
- // info to the console.
- normalTracking = !normalTracking;
- if (!normalTracking)
- hideNormalMarker();
- break;
- case 'l': case 'L':
- // L key pressed. Toggle location tracking. Each time the mouse moves, do a pick
- // and place nubbin at picked location.
- locationTracking = !locationTracking;
- if (!locationTracking)
- hidePositionMarker();
- break;
- case '1':
- // prints paths to all IndexedFaceSet nodes.
- searchAndPrint("IndexedFaceSet");
- break;
- case '2':
- // prints paths to all TimeSensor nodes.
- searchAndPrint("TimeSensor");
- break;
- case '3':
- // prints paths to all Group nodes.
- searchAndPrint("Group");
- break;
- case '4':
- // prints paths to all nodes.
- searchAndPrint("Node");
- break;
- case '5':
- // prints paths to all nodes.
- searchAndPrint("Switch");
- break;
- case '?':
- // Print help message.
- System.out.println("-----------------------------------");
- System.out.println("KEY: ACTION:");
- System.out.println("n NORMAL picking toggle. Turns tracking of surface normal on/off");
- System.out.println("l LOCATION picking toggle. Turns tracking of picked location on/off");
- System.out.println("w WRITE scene to textArea in VRML-like syntax");
- System.out.println("1 #1--diagnostic - search for IndexedFaceSets");
- System.out.println(" and print paths to them");
- System.out.println("2 #2--diagnostic - search for TimeSensors");
- System.out.println(" and print paths to them");
- System.out.println("3 #3--diagnostic - search for Groups");
- System.out.println(" and print paths to them");
- System.out.println("4 #4--diagnostic - search for all Nodes");
- System.out.println(" and print paths to them");
- }
- }
- }
- return false;
- }
- //}} DeviceObserver methods
-
- /**
- * Searches for paths to all nodes of the given type, printing the results
- * to the console.
- */
- void searchAndPrint(String typeName) {
- System.out.println("RESULTS OF SEARCH FOR ALL " + typeName + "s :");
- Searcher s = getNewSearcher();
- s.setType(typeName);
- Node[][] paths = s.searchAll(getScene());
- if (paths == null || paths.length == 0) {
- System.out.println("No paths found");
- return;
- }
- System.out.println("Number of paths is " + paths.length);
- for (int i = 0; i < paths.length; i++) {
- Node[] p = paths[i];
- System.out.println("PATH " + i);
- for (int j = 0; j < p.length; j++) {
- if (p[j] == null)
- System.out.println(" node " + j + " is null");
- else {
- String name = p[j].getDEFName();
- if (name == null)
- name = "";
- System.out.println(" node " + j + " name:" + name + " type " + p[j].getTypeName());
- }
- }
- }
- System.out.println("-------------------------------------------");
- }
-
- Picker myPicker;
- private Node[] pickPath;
- /**
- * Tracks the current cursor location with a nubbin or an arrow.
- *
- * If normalTracking, then an arrow will be stuck at the picked
- * location, pointing in the direction of the pick-point-normal.
- *
- * If locationTracking, then a nubbin will be placed at the picked location.
- */
- void trackPick() {
- if (myPicker == null)
- myPicker = getNewPicker();
- myPicker.setPickInfo(Picker.POINT, (normalTracking || locationTracking));//Only needed for these two
- myPicker.setPickInfo(Picker.NORMAL, normalTracking);//Only if normalTracking
- // Hide the markers, so that the markers can't be picked.
- hideNormalMarker();
- hidePositionMarker();
- pickPath = myPicker.pickClosest(curMouseX, curMouseY);
- float[] pickedPoint = myPicker.getPickInfo(Picker.POINT);//Garbage if (!normalTracking&&!locationTracking)
- float[] pickedNormal = myPicker.getPickInfo(Picker.NORMAL);//Garbage if !normalTracking
- if (pickPath != null){
- if (locationTracking)
- showPositionMarker(pickedPoint);
- if (normalTracking)
- showNormalMarker(pickedPoint, pickedNormal);
- }
- mouseMoved = false;
- }
-
- // These store references to the markers
- Transform positionMarker, normalMarker;
- // These are cached to easily call addChidren/removeChildren
- Node[] positionMarkerKidArray;
- Node[] normalMarkerKidArray;
- // Scale applied to the marker,
- // can be set with the markerScale parameter in the html file.
- float[] markerScale = { .1f, .1f, .1f};
-
- /**
- * Hides the normal marker by removing from the scene.
- */
- void hideNormalMarker(){
- if (normalMarker != null) {
- getScene().removeChildren(normalMarkerKidArray);
- }
- }
- /**
- * Hides the position marker by removing from the scene.
- */
- void hidePositionMarker(){
- if (positionMarker != null){
- getScene().removeChildren(positionMarkerKidArray);
- }
- }
- /**
- * Shows the normal marker and places according to input parameters.
- */
- void showNormalMarker(float[/*3*/]position, float[/*3*/] direction){
- if (normalMarker == null){
- initMarkerGeoms();
- }
- normalMarker.translation.setValue(position);
- //Set rotation to point the y axis towards the direction. Axis is cross product, angle is acos(dotProduct)
- // Axis is cross product yAxis.cross(direction), which is (dz, 0, -dx)
- normalMarker.rotation.getValue()[0] = direction[2];
- normalMarker.rotation.getValue()[1] = 0;
- normalMarker.rotation.getValue()[2] = -direction[0];
- MatUtil.normalize(normalMarker.rotation.getValue()); // will just normalize 1st 3 of 4 components
- normalMarker.rotation.getValue()[3] = (float) Math.acos(direction[1]); // angle whose cosine is dotprod of (0,1,0) and direction
- normalMarker.rotation.setValue(normalMarker.rotation.getValue());
- getScene().addChildren(normalMarkerKidArray);
- }
- /**
- * Shows the position marker and places according to input parameters.
- */
- void showPositionMarker(float[/*3*/]position){
- if (positionMarker == null){
- initMarkerGeoms();
- }
- positionMarker.translation.setValue(position);
- getScene().addChildren(positionMarkerKidArray);
- }
-
- /**
- * Reads the file given by the parameter "markerGeometry"
- * and searches inside for two named nodes:
- * "PositionMarker" and "NormalMarker"
- *
- * Saves these and also scales them by markerScale (which
- * may be set as an html input parameter)
- */
- void initMarkerGeoms(){
- Transform markerRoot = new Transform();
- String markerGeomString = applet.getParameter("markerGeometry");
- if (markerGeomString == null){
- System.out.println("Error -- Mo markerGeometry parameter specified for applet");
- System.out.println(" Can not show picked location");
- return;
- }
- String[] urlArray = { markerGeomString };
- // Don't load in a separate thread:
- boolean wasSeparate = isLoadResourcesInSeparateThread();
- setLoadResourcesInSeparateThread(false);
- loadURL(urlArray, markerRoot);
- setLoadResourcesInSeparateThread(wasSeparate);
- if (markerRoot == null) {
- throw new Shout3DException("ERROR - could not load marker geometry");
- }
- Searcher mySearcher = getNewSearcher();
-
- // initialize positionMarker
- mySearcher.setDefName("PositionMarker");
- Node[] sResult = mySearcher.searchFirst(markerRoot);
- if (sResult==null){
- throw new Shout3DException("ERROR - could not find PositionMarker");
- }
- positionMarker = (Transform) sResult[sResult.length-1];
- // Create the array used to add the positionMarker to the scene.
- positionMarkerKidArray = new Node[1];
- positionMarkerKidArray[0] = positionMarker;
-
- // initialize normalMarker
- mySearcher.setDefName("NormalMarker");
- sResult = mySearcher.searchFirst(markerRoot);
- if (sResult==null){
- throw new Shout3DException("ERROR - could not find NormalMarker");
- }
- normalMarker = (Transform) sResult[sResult.length-1];
- // Create the array used to add the normalMarker to the scene.
- normalMarkerKidArray = new Node[1];
- normalMarkerKidArray[0] = normalMarker;
-
- String markerScaleParamString = applet.getParameter("markerScale");
- if (markerScaleParamString != null){
- markerScale[0] = markerScale[1] = markerScale[2] = Float.valueOf(markerScaleParamString).floatValue();
- }
-
- positionMarker.scale.setValue(markerScale);
- normalMarker.scale.setValue(markerScale);
-
- }
-
- }
-
- /**
- * A little class that puts a text area in its own
- * free floating frame.
- */
- class WriterTextFrame extends Frame {
- TextArea myTextArea;
- WriterTextFrame() {
- setLayout(new BorderLayout());
- myTextArea = new TextArea();
- this.add("Center",myTextArea);
- }
-
- TextArea getTextArea() { return myTextArea; }
- }
-